home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MYIO.ZIP / MYSTREAM.CPP < prev    next >
C/C++ Source or Header  |  1995-11-02  |  4KB  |  143 lines

  1. // Mystream.cpp
  2. // Implementation of ios interface classes for Myio
  3. //
  4. // Written by David L. Nugent
  5. //
  6.  
  7. # include <iostream.h>
  8. # include "Mystream.h"
  9. # if defined(_MSC_VER)
  10. #  include <memory.h>
  11. # else
  12. #  include <stdlib.h>
  13. # endif
  14.  
  15.     // Mystreambuf constructor
  16.     // This simply initialises the base class streambuf
  17.     // (it is initially empty with no buffer allocated)
  18.     // and register the Myio object
  19.     // Note: we _could_ set the stream unbuffered here,
  20.     // which is useful for stdio handles, so that the
  21.     // streambuf functions overflow() and underflow()
  22.     // get called on every character rather than when
  23.     // the streambuf buffer is full
  24.  
  25. Mystreambuf::Mystreambuf (Myio * mPtr)
  26.     : streambuf (), mptr(mPtr)
  27. {
  28. //  unbuffered(1);  // Uncomment to make unbuffered
  29. }
  30.  
  31.     // Mystreambuf()
  32.     // Called when streambuf owned buffer is full
  33.     // or when stream is flushed
  34.     // Our job here is to empty the streambuf
  35.     // write buffer and reset the 'put' pointers.
  36.  
  37. int
  38. Mystreambuf::overflow (int c)
  39. {
  40.     int written;
  41.  
  42.         // Handle unbuffered stream
  43.  
  44.     if (unbuffered())       // Handle the simple case first
  45.     {
  46.         if (c == EOF)   // Special case, this only flushes
  47.             return 0;
  48.         char ch = char(c);  // Write the byte directly
  49.         written = mptr->write (&ch, 1);
  50.         return (written) ? c : EOF;
  51.     }
  52.  
  53.         // Handle buffered stream
  54.  
  55.     if (!base())        // Need to allocate a buffer
  56.         allocate();
  57.  
  58.     if (base())         // Test for memory allocation error
  59.     {
  60.         char * ep = base() + (blen() / 2);
  61.         if (!pbase())   // Set put pointers if not set up
  62.             setp (base(), ep);
  63.         int bytes = pptr() - pbase();   // Bytes to write
  64.         if (bytes)
  65.         {
  66.             written = mptr->write (pbase(), bytes);
  67.             if (!written)
  68.                 return EOF;
  69.             bytes += written;
  70.             if (bytes)  // Some is still waiting to be written
  71.                 memcpy (base(), base() + written, bytes);
  72.         }
  73.         setp (base() + bytes, ep);  // Reset 'put' pointers
  74.         return (c == EOF) ? 0 : sputc (c);  // Put pending chr in buf
  75.     }
  76.     return EOF;
  77. }
  78.  
  79.     //
  80.     // underflow() indicates that the input queue
  81.     // is empty and needs more data
  82.     //
  83.  
  84. int
  85. Mystreambuf::underflow (void)
  86. {
  87.     int bytes;
  88.  
  89.         // Handle an unbuffered stream
  90.  
  91.     if (unbuffered())
  92.     {
  93.         bytes = mptr->read (&_back[1], 1);
  94.         if (!bytes)
  95.         {
  96.             setg (0, 0, 0);
  97.             return EOF;
  98.         }
  99.         setg (_back, _back + 1, _back + 2);
  100.         return (unsigned char)_back[1];
  101.     }
  102.  
  103.         // Handle a buffered stream
  104.  
  105.     if (!base())        // Need to allocate a buffer
  106.         allocate();
  107.  
  108.     if (base())
  109.     {
  110.         char * gp = base() + blen() / 2;
  111.         if (gptr() >= egptr())
  112.         {                   // Read into the buffer from stream
  113.             overflow ();    // Flush output in case we need it
  114.             bytes = mptr->read (gp + 1, blen() / 2 - 1);
  115.             setg (gp, gp + 1, gp + bytes + 1);
  116.         }
  117.         if (gptr() < egptr())   // Get from buffer
  118.             return (unsigned char) *gptr();
  119.     }
  120.     return EOF;
  121. }
  122.  
  123.     //
  124.     // sync() needs to empty both put and get
  125.     // buffered. It will do this by calling
  126.     // overflow and simply resetting the get
  127.     // pointers to their default location.
  128.     //
  129.  
  130. int
  131. Mystreambuf::sync (void)
  132. {
  133.     if (!unbuffered())
  134.     {
  135.         overflow ();                // Force output
  136.         char * gp = base();
  137.         setp (gp, gp + blen() / 2);
  138.         gp = base() + blen() / 2;
  139.         setg (0, 0, 0);
  140.     }
  141.     return 0;
  142. }
  143.